import { computed, Ref, ref,watch } from "vue"

/**
 * 创建一个空层
 * @param rowSize 
 * @returns 
 */
function createEmptyLayer(rowSize:number,defaultVal=0){
    const matrix:any[]=[]
    for(let i=0;i<rowSize;i++){
        const row:number[]=[]
        for(let j=0;j<rowSize;j++){
            row.push(defaultVal)
        }
        matrix.push(row)
    }
    return matrix
}

/**
 * 创建雷的序号
 * 思想：给每一个cell一个随机数
 * 之后进行排序,再取前mineSize个雷的序号
 * @param cellSize 
 * @returns 
 */
function createMineSorts(cellSize:number,mineSize:number):number[]{
    const tmp:any[]=[]
    for(let i=0;i<cellSize;i++){
        tmp.push({i,p:Math.random()})
    }
    tmp.sort((a, b) => a.p - b.p)

    return tmp.slice(0,mineSize).map(item=>item.i);
}

function useInit(){
    // 默认值
    const rowSize=9
    const width=rowSize
    const height=rowSize
    const mineSize=10

    // 雷区层，记录真实雷的位置
    const mineLayer:Ref<any[]>=ref([])
    // 统计层，根据真实雷区，计算周围雷的数量(0~8表示统计数量)；仅挖开无事层才展示
    const statisticsLayer:Ref<any[]>=ref([])
    // 揭示层，记录用户的操作记录（未挖掘0；挖开无事1；标雷2；挖到雷3）
    const revealLayer:Ref<any[]>=ref([])


    // 结束标记。0进行中；1成功；2失败
    const endMark=ref(0)

    const revealCount:Ref<number>=ref(0)
    watch(revealCount,(newVal,oldVal)=>{
        if(newVal==rowSize*rowSize && endMark.value==0){
            console.log('you win!!!')
            endMark.value=1
        }
    })
    const endInfo:Ref<string>=computed(()=>{
        switch(endMark.value){
            case 0:
                return '进行中'
            case 1:
                return '成功'
            case 2:
                return '失败'
            default:
                return '???'
        }
    })

    /**
     * 预期给雷区埋雷
     * @returns 
     */
    function initMineLayer(){
        mineLayer.value=createEmptyLayer(rowSize)
        const mineSorts=createMineSorts(rowSize*rowSize,mineSize)
        for(const sort of mineSorts ){
            const row=Math.floor(sort/rowSize)
            const col=sort%rowSize
            mineLayer.value[row][col]=1
        }
    }

    // 计算周遭区域
    function calcRoundCell({row,col}){
        const res:any[]=[]
        for(let i=row-1;i<=row+1;i++){
            for(let j=col-1;j<=col+1;j++){
                if(0<=i&&i<height&&0<=j&&j<width){
                    res.push({row:i,col:j})
                }
            }
        }
        return res
    }

    // 根据真实雷区，计算周围雷的数量
    function initStatisticsLayer(){
        statisticsLayer.value=createEmptyLayer(rowSize)
        for(let row=0;row<height;row++){
            for(let col=0;col<width;col++){
                const mineMark=mineLayer.value[row][col]
                if(mineMark==0){
                    continue
                }
                const roundCells=calcRoundCell({row,col})
                for(const cell of roundCells){
                    statisticsLayer.value[cell.row][cell.col]++
                }
            
            }
        }
    }

    function initRevealLayer(){
        revealLayer.value=createEmptyLayer(rowSize)
    }


    // 展示cell
    function showCell({row,col}){
        if(revealLayer.value.length==0){
            return {
                content:'',
                revealMark:0
            }
        }
        // console.log('layer:',revealLayer.value)
        // console.log('rc:',row,col);
        const revealMark=revealLayer.value[row][col]
        
        if(revealMark==0){
            return {
                content:'',
                revealMark
            }
        }
        if(revealMark==1){
            return {
                content:statisticsLayer.value[row][col]||'',
                revealMark
            }
        }
        if(revealMark==2){
            return {
                content:'F',
                revealMark
            }
        }
        if(revealMark==3){
            return {
                content:'R',
                revealMark
            }
        }
        return {}
    }

    const showLayer:Ref<any[]>=computed(()=>{
        const res:any[]=[]
        for(let r=0;r<height;r++){
            const tmp:any[]=[]
            for(let c=0;c<width;c++){
                tmp.push(showCell({row:r,col:c}))
            }
            res.push(tmp)
        }
        return res
    })


    /**
     * 揭示
     * @param param0 
     */
    function handleReveal({row,col}){
        if(endMark.value!==0){
            console.log('game overed!');
            return
        }
        // console.log(revealLayer.value);
        const revealMark=revealLayer.value[row][col]
        if(revealMark!=0){
            return;
        }
        const mineMark=mineLayer.value[row][col]
        if(mineMark){
            revealLayer.value[row][col]=3
            endMark.value=2
        }else{
            revealLayer.value[row][col]=1
            revealCount.value++
            // 如果统计数为0，则自动扩散
        }
    }

    // 标雷
    function handleFlag({row,col}){
        if(endMark.value!==0){
            console.log('game overd!')
            return
        }
        const revealMark=revealLayer.value[row][col]
        if(revealMark==0){
            revealLayer.value[row][col]=2
            revealCount.value++
            return
        }
        if(revealMark==2){
            revealLayer.value[row][col]=0
            revealCount.value--
        }
    }

    // 自动揭示周遭
    function handleRevealRound({row,col}){
        if(endMark.value!==0){
            console.log('game overd!')
            return
        }
        const revealMark=revealLayer.value[row][col]
        if(revealMark!==1){
            console.log('not revealed');
            return
        }
        // 当前真实统计数量，与标旗数量一致时，则自动将周遭一圈的区域外出
        const mineCount=statisticsLayer.value[row][col]
        const roundCells=calcRoundCell({row,col})
        const flagCount=roundCells.filter(cell=>revealLayer.value[cell.row][cell.col]===2).length
        if(flagCount===mineCount){
            for(const cell of roundCells){
                if(revealLayer.value[cell.row][cell.col]===0){
                    revealLayer.value[cell.row][cell.col]=1
                }
            }
        }

    }

    // 自动揭示0(可以暂时不考虑)
    function revealAutoZero({row,col}){

    }


    function initAll(){
        initMineLayer()
        initStatisticsLayer()
        initRevealLayer()
        endMark.value=0
        revealCount.value=0
    }

    

    // initAll()

    return {
        mineLayer,revealLayer,statisticsLayer,endInfo,
        initAll,
        handleReveal,
        handleFlag,
        handleRevealRound,
        showLayer
    }
}

export {useInit}